package com.crm.system.service.impl.csd.reviewManager;

import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DhPageInfo;
import com.crm.common.model.Enum.NewsEnum;
import com.crm.common.model.Enum.StatusCodeEnum;
import com.crm.common.util.CommonUtils;
import com.crm.common.util.ESUtil;
import com.crm.model.entity.MessageManager.Message;
import com.crm.model.entity.csd.reviewManager.PutOnRecordInformation;
import com.crm.model.entity.customerManager.Customer;
import com.crm.model.entity.customerManager.CustomerPool;
import com.crm.model.entity.customerManager.CustomerReceive;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.entity.systemManager.SysParameterSetting;
import com.crm.model.qo.csd.reviewManager.PutOnRecordInformationAddQO;
import com.crm.model.qo.csd.reviewManager.PutOnRecordInformationQO;
import com.crm.model.vo.csd.reviewManager.PutOnRecordInformationVO;
import com.crm.redis.service.customerManager.CustomerRedisService;
import com.crm.service.csd.reviewManager.PutOnRecordInformationDbService;
import com.crm.service.customerManager.CustomerDbService;
import com.crm.service.customerManager.CustomerPoolDbService;
import com.crm.service.customerManager.CustomerReceiveDbService;
import com.crm.service.customerManager.CustomerRelationDbService;
import com.crm.service.messageManager.MessageDbService;
import com.crm.service.systemManager.ParameterSettingDbService;
import com.crm.system.service.csd.reviewManager.PutOnRecordInformationService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author yincuimei
 * @Date 2021/8/10 9:00
 * (客服部)-审核管理-》备案信息
 */
@Service
public class PutOnRecordInformationServiceImpl implements PutOnRecordInformationService {
    @Autowired
    private PutOnRecordInformationDbService putOnRecordInformationDbService;
    @Autowired
    ParameterSettingDbService parameterSettingDbService;
    @Autowired
    private CustomerPoolDbService customerPoolDbService;
    @Autowired
    private CustomerDbService customerDbService;
    @Autowired
    private CustomerRelationDbService customerRelationDbService;
    @Autowired
    CustomerRedisService customerRedisService;
    @Autowired
    private MessageDbService messageDbService;
    @Autowired
    private CustomerReceiveDbService customerReceiveDbService;

    @Value("${esurl}")
    public String ESurl;
    /**
     * 备案信息列表
     * @param putOnRecordInformationQO  --查询条件
     * @param pageIndex/pageSize        --页码/分页大小
     * @param sortName                  --排序字段
     * @param sortOrder                 --排序规则
     * @author yincuimei
     * @return
     */
    @Override
    public DhPageInfo<PutOnRecordInformationVO> selectPutOnRecordInformationVOList(PutOnRecordInformationQO putOnRecordInformationQO, Integer pageIndex, Integer pageSize, String sortName, String sortOrder) {
        if (pageIndex != null && pageSize != null) {//分页
            PageHelper.startPage(pageIndex, pageSize);
        }

        //排序
        StringBuilder order = new StringBuilder();
        if (!StringUtils.isBlank(sortName) && !StringUtils.isBlank(sortOrder)) {
            switch (sortName) {
                case "createTm": {
                    order.append("t.create_tm ").append(sortOrder);//(备案时间)创建时间
                }
                break;
                default:
                    break;
            }
        }

        List<PutOnRecordInformationVO> list = putOnRecordInformationDbService.selectPutOnRecordInformationVOList(putOnRecordInformationQO,order.toString());
        PageInfo<PutOnRecordInformationVO> pageInfo = new PageInfo(list);
        return new DhPageInfo<PutOnRecordInformationVO>(pageInfo,list);
    }

    /**
     * 新增备案信息(客户表、备案信息表新增)
     * 业务描述:
     *  1. 判断客户池容量
     *     (1).判断系统设置的客户池数量和客户表里非会员客户数量
     *     (2).判断所选公司的客户池数量和客户表里所在客户池的数量
     *  2. 判断企业名称或企业信用代码是否存在(去redis或chs_customer客户表里判重)
     *    (1).客户名称或企业信用代码存在: 返回提示("企业名称或企业信用代码已存在"):
     *        redis里存在直接返回提示,
     *        redis不存在，客户表里存在，返回提示并且往redis里添加这条记录
     * 3. 执行新增操作
     *   (1).新增客户(chs_customer);
     *   (2).新增到redis;
     *   (3).新增备案信息(csd_put_on_record_information)
     * （备注:企业名称即客户表里的客户名称)
     * 4. 发送消息(msg_message)
     * @param putOnRecordInformationAddQO --新增备案信息参数
     * @author yincuimei
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public JSONObject insertPutOnRecordInformation(PutOnRecordInformationAddQO putOnRecordInformationAddQO) {
        JSONObject jsonResult = new JSONObject();//返回结果
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        String accountId = userAccount.getAccountId();//登录人账号ID

        String companyName = putOnRecordInformationAddQO.getCompanyName();//企业名称
        String unifiedSocialCreditCode  = putOnRecordInformationAddQO.getUnifiedSocialCreditCode();//企业信用代码
        String affiliationCompanyId = putOnRecordInformationAddQO.getAffiliationCompanyId();//所属分公司
        String salesPersonId = putOnRecordInformationAddQO.getSalesPersonId();//所属业务员

        Date operateDate = new Date();//操作时间

        //系统设置客户池容量
        SysParameterSetting sysParameterSetting = parameterSettingDbService.selectSystemParameterSetting();
        int sysCount = sysParameterSetting != null ? sysParameterSetting.getMaxCustomerNum() : 0;
        //根据所属业务员查询客户表里非会员客户数量
        long customerCount = customerDbService.selectNonmemberCustomerCountByAccountId(salesPersonId);
        if (customerCount >= sysCount) {//超出系统设置的客户池容量
            jsonResult.put("code","C00001");
            jsonResult.put("message","超出客户容量!");
            return jsonResult;
        }

        //查询所选公司对应的全国公有池
        CustomerPool customerPool = customerPoolDbService.selectCustomerPoolCompanyId(affiliationCompanyId);
        if (customerPool == null) {//所属公司对应的全国公有池不存在
            jsonResult.put("code", "C00002");
            jsonResult.put("message", "您所属公司对应的全国公有池不存在，请联系管理员!");
            return jsonResult;
        }

        //所选公司客户池容量
        int capacity = customerPool.getCapacity();
        //根据客户池ID查询客户池已经存在的客户数
        long count = customerDbService.selectCustomerCount(customerPool.getCustomerPoolId());
        if (count < capacity) {//客户池容量未超,判断是否重复(客户关系表、redis、客户表)
            //根据企业名称查询是否已关联客户(chs_customer_relation)
            Boolean result = customerRelationDbService.selectCustomerRelationByName(companyName);
            if (result) {//客户关联表已存在，企业名称已关联客户
                jsonResult.put("code","C00003");
                jsonResult.put("message","客户名称已关联客户");
                return jsonResult;
            }
            //查询redis、客户表(redis不存在查询客户表，客户表存在、redis不存在则存入redis)
            Boolean isCustomerRepeat = customerDbService.selectCustomerIfRepeated(companyName, unifiedSocialCreditCode);
            if (!isCustomerRepeat) {
                Customer customer = new Customer();
                customer.setCustomerId(CommonUtils.getGUID());//主键
                customer.setCustomerName(companyName);//客户名称
                customer.setCustomerNumber(createCustomerNumber());//客户编号
                customer.setCustomerType("0");//客户类型
                customer.setUnifiedSocialCreditCode(unifiedSocialCreditCode);//统一社会信用代码
                customer.setCreatePeopleId(accountId);//创建人ID
                customer.setCreateTm(operateDate);//创建时间
                customer.setUpdatePeopleId(accountId);//更新人ID
                customer.setUpdateTm(operateDate);//更新时间
                customer.setAccountId(salesPersonId);//所有人
                customer.setOwnerId(salesPersonId);//所有人
                customer.setCompanyName(affiliationCompanyId);//所属分公司
                customer.setAssignedPersonId(salesPersonId);//被分配人ID
                customer.setDeleteStatus(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));//删除状态
                customer.setCustomerPoolId(customerPool.getCustomerPoolId());//客户池ID
                customer.setCurrentStatus((short)2);//目前状态---0: 未领取; 1: 已领取(我领取的客户);2: 已分配(分配给我的客户);3: 自建客户(用户模块我自建的客户);
                customer.setContactPerson(putOnRecordInformationAddQO.getCustomerName());//联系人
                customer.setContactPersonPhone(putOnRecordInformationAddQO.getCustomerPhone());//联系人电话
                customerDbService.insertCustomer(customer);//插入客户表
                customerRedisService.setCustomerByNameAndCode(customer);//将客户信息插入Redis
                ESUtil.syncCustomer(transBean2Map(customer),accountId,"客服部-备案信息-新建备案",ESurl);

                //插入客户领取/分配记录表
                CustomerReceive customerReceive = new CustomerReceive();
                customerReceive.setCustomerReceiveId(CommonUtils.getGUID());//主键
                customerReceive.setReceivePeopleId(salesPersonId);//分配人
                customerReceive.setReceiveTm(new Date());//分配时间
                customerReceive.setCustomerPoolFromId(customer.getCustomerPoolId());
                customerReceive.setReceiveWay(2);//领取方式：1-领取；2:分配
                customerReceive.setCustomerId(customer.getCustomerId());//客户ID
                customerReceiveDbService.insertCustomerReceive(customerReceive);

                PutOnRecordInformation putOnRecordInformation = new PutOnRecordInformation();
                BeanUtils.copyProperties(putOnRecordInformationAddQO,putOnRecordInformation);
                putOnRecordInformation.setRecordInformationId(CommonUtils.getGUID());
                putOnRecordInformation.setCreatePeopleId(accountId);
                putOnRecordInformation.setUpdatePeopleId(accountId);
                putOnRecordInformation.setCreateTm(operateDate);
                putOnRecordInformation.setUpdateTm(operateDate);
                putOnRecordInformation.setDeleteStatus((short)StatusCodeEnum.NORMAL_CODE.getState());
                //3. 插入备案信息表(csd_put_on_record_information)
                result = putOnRecordInformationDbService.insertPutOnRecordInformation(putOnRecordInformation);
                if(result){
                    //4. 发送消息(msg_message)
                    if(!StringUtils.isBlank(salesPersonId)){
                        Message message = getMessageEntity(userAccount,putOnRecordInformationAddQO,operateDate);
                        messageDbService.addMessage(message);
                    }
                    jsonResult.put("code", "000000");
                    jsonResult.put("message", "备案成功!");
                }else{
                    jsonResult.put("code", "-1");
                    jsonResult.put("message", "备案失败,请稍后再试!");
                }
                return jsonResult;
            }else {
                jsonResult.put("code","C00004");
                jsonResult.put("message","客户名称或统一社会信用代码已存在");
                return jsonResult;
            }
        } else {//超出客户池容量
            jsonResult.put("code","C00005");
            jsonResult.put("message","超出客户池容量!");
            return jsonResult;
        }
    }

    /**
     * 对象装换map
     * @param obj
     * @return
     */
    private static Map<String, Object> transBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 得到property对应的getter方法
                Method getter = property.getReadMethod();
                Object value = getter.invoke(obj);
                map.put(key, value);
            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }
        return map;
    }

    /**
     * 客户-生成客户编号
     * @return
     */
    public String createCustomerNumber() {
        String datetime = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String newCustomerNumber = datetime + "00001";
        String maxCustomerNumber = customerDbService.selectMaxCustomerNumber(datetime);
        if (Objects.nonNull(maxCustomerNumber)) {
            if (maxCustomerNumber.length() < 8) {
                maxCustomerNumber = customerDbService.selectMaxCustomerNumber(datetime);
                if (Objects.isNull(maxCustomerNumber)) {
                    return newCustomerNumber;
                }
            }
            if (datetime.equals(maxCustomerNumber.substring(0, 8))) {
                newCustomerNumber = datetime + String.format("%05d", Integer.parseInt(maxCustomerNumber.substring(8)) + 1);
            }
        }
        return newCustomerNumber;
    }

    /**
     * 发送消息实体
     * @param userAccount                  --当前用户
     * @param putOnRecordInformationAddQO  --新增备案实体
     * @param operateDate                  --操作时间
     * @author yincuimei
     * @return
     */
    public Message getMessageEntity(UserAccount userAccount,PutOnRecordInformationAddQO putOnRecordInformationAddQO,Date operateDate){
        Message message = new Message();
        message.setMessageId(CommonUtils.getGUID());//主键
        message.setSenderId(userAccount.getAccountId());//发送人ID
        message.setSendTm(operateDate);//发送时间
        message.setSendCompanyId(userAccount.getCompanyId());//发送人所属公司
        message.setSendDeleteStatus(StatusCodeEnum.NORMAL_CODE.getState());
        message.setThemeId(CommonUtils.getGUID());//主题id
        message.setTheme("新增备案");//主题
        message.setNewsDetail("【" + putOnRecordInformationAddQO.getCompanyName() + "】备案成功");//消息详情
        message.setSendNewsReadType(NewsEnum.NO_READ.getValue());//发送消息读取类型  0已读消息 1未读消息
        message.setNewsType(NewsEnum.APPROVAL_MESS.getValue());//消息类型 2审批消息 3回款消息 4系统消息 5普通消息
        message.setMarkImportant(NewsEnum.NO_IMPORTANT.getValue());//标为重要 0不重要 1重要
        message.setReceiverId(putOnRecordInformationAddQO.getSalesPersonId());//接收人id
        message.setReceiverTm(operateDate);//接收时间
        message.setReceiverCompanyId(putOnRecordInformationAddQO.getAffiliationCompanyId());//接收人公司id
        message.setReceiverNewsReadType(NewsEnum.NO_READ.getValue());//接收消息读取类型  0已读消息 1未读消息
        message.setReceiverDeleteStatus(StatusCodeEnum.NORMAL_CODE.getState());//接收删除状态---0: 正常; 1: 已删除
        message.setCreatePeopleId(userAccount.getAccountId());//创建人
        message.setCreateTm(operateDate);//创建时间
        message.setUpdatePeopleId(userAccount.getAccountId());//更新人
        message.setUpdateTm(operateDate);//更新时间
        message.setDeleteStatus(StatusCodeEnum.NORMAL_CODE.getState());//删除状态---0: 正常; 1: 已删除
        return message;
    }
}
